package com.yungu.swift.lbs.trace.baidu.util;

import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.yungu.swift.lbs.model.dto.LatLngDto;
import com.yungu.swift.lbs.trace.baidu.model.TrackPoint;
import com.yungu.swift.lbs.trace.baidu.track.GetDistanceRequest;
import com.yungu.swift.lbs.trace.baidu.track.GetTrackRequest;
import com.yungu.swift.lbs.trace.baidu.track.IllegalTrackArgumentException;
import com.yungu.swift.lbs.trace.baidu.track.ListEntityRequest;
import com.yungu.swift.utils.JsonUtils;
import com.yungu.swift.utils.StringUtils;

import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * track工具类
 *
 * @author baidu
 */
public class TrackUtils {

    /**
     * 检查经纬度
     *
     * @param latLngDto
     * @return
     */
    public static boolean checkLatLng(LatLngDto latLngDto) {
        if (null == latLngDto) {
            throw new IllegalTrackArgumentException("latLngDto can not be null");
        }

        if (Math.abs(latLngDto.getLatitude()) > 90 || Math.abs(latLngDto.getLongitude()) > 180) {
            throw new IllegalTrackArgumentException("latLngDto is invalid value");
        }

        return true;
    }

    /**
     * 组装单个轨迹点
     *
     * @param trackPoint
     * @param parameters
     */
    public static void packPoint(TrackPoint trackPoint, StringBuilder parameters) {
        LatLngDto location = trackPoint.getLocation();
        if (TrackUtils.checkLatLng(location)) {
            parameters.append("&latitude=").append(location.getLatitude());
            parameters.append("&longitude=").append(location.getLongitude());
        }

        parameters.append("&loc_time=").append(trackPoint.getLocTime());

        if (null == trackPoint.getCoordType()) {
            throw new IllegalTrackArgumentException("coordType can not be null.");
        }

        parameters.append("&coord_type_input=").append(trackPoint.getCoordType().name());
        parameters.append("&speed=").append(trackPoint.getSpeed());
        parameters.append("&direction=").append(trackPoint.getDirection());
        parameters.append("&height=").append(trackPoint.getHeight());
        parameters.append("&radius=").append(trackPoint.getRadius());

        if (!BaiduCommonUtils.isNullOrEmpty(trackPoint.getObjectKey())) {
            parameters.append("&_obejct_key=").append(HttpUtils.urlEncode(trackPoint.getObjectKey()));
        }

        if (null != trackPoint.getColumns()) {
            packColumns(trackPoint.getColumns(), parameters);
        }
    }

    /**
     * 组装轨迹点列表
     *
     * @param points     轨迹点列表，Map中key为entityName， value为轨迹点集
     * @param parameters json格式轨迹点信息
     */
    public static void packPoints(Map<String, List<TrackPoint>> points, StringBuilder parameters) {
        if (null == points) {
            throw new IllegalTrackArgumentException("track points can not be null.");
        }
        ArrayNode jsonArray = JsonUtils.newArrayNode();
        try {
            Set<Map.Entry<String, List<TrackPoint>>> entries = points.entrySet();
            for (Map.Entry<String, List<TrackPoint>> entry : entries) {
                String entityName = entry.getKey();
                List<TrackPoint> trackPoints = entry.getValue();
                if (null == trackPoints) {
                    continue;
                }
                for (TrackPoint trackPoint : trackPoints) {
                    if (null == trackPoint) {
                        continue;
                    }
                    ObjectNode jsonObject = JsonUtils.newJsonNode();
                    jsonObject.put("entity_name", entityName);
                    jsonObject.put("loc_time", trackPoint.getLocTime());

                    LatLngDto location = trackPoint.getLocation();
                    if (TrackUtils.checkLatLng(location)) {
                        jsonObject.put("latitude", location.getLatitude());
                        jsonObject.put("longitude", location.getLongitude());
                    }

                    if (null == trackPoint.getCoordType()) {
                        throw new IllegalTrackArgumentException("coordType can not be null.");
                    }
                    jsonObject.put("coord_type_input", trackPoint.getCoordType().name());
                    jsonObject.put("speed", trackPoint.getSpeed());
                    jsonObject.put("direction", trackPoint.getDirection());
                    jsonObject.put("height", trackPoint.getHeight());
                    jsonObject.put("radius", trackPoint.getRadius());

                    Map<String, String> columns = trackPoint.getColumns();
                    if (null != columns) {
                        packColumns(columns, jsonObject);
                    }
                    jsonArray.add(jsonObject);
                }
            }
        } catch (Exception ex) {
            ex.printStackTrace();
        }

        parameters.append("&point_list=").append(jsonArray.toString());

    }

    /**
     * 组装获取里程参数表
     *
     * @param getDistanceRequest
     * @param parameters
     */
    public static void packDistance(GetDistanceRequest getDistanceRequest, StringBuilder parameters) {
        if (null == getDistanceRequest) {
            throw new IllegalTrackArgumentException("DistanceRequest can not be null.");
        }
        if (StringUtils.isEmpty(getDistanceRequest.getEntityName())) {
            throw new IllegalTrackArgumentException("entityName can not be null.");
        }
        if (getDistanceRequest.getStartTime() == 0) {
            throw new IllegalTrackArgumentException("start_time can not be null.");
        }
        if (getDistanceRequest.getEndTime() == 0) {
            throw new IllegalTrackArgumentException("end_time can not be null.");
        }
        parameters.append("&entity_name=").append(getDistanceRequest.getEntityName());
        parameters.append("&start_time=").append(getDistanceRequest.getStartTime());
        parameters.append("&end_time=").append(getDistanceRequest.getEndTime());
        if (StringUtils.isNotEmpty(getDistanceRequest.getIsProcessed())) {
            parameters.append("&is_processed=").append(getDistanceRequest.getIsProcessed());
        }
        if (StringUtils.isNotEmpty(getDistanceRequest.getProcessOption())) {
            parameters.append("&process_option=").append(getDistanceRequest.getProcessOption());
        }
        if (StringUtils.isNotEmpty(getDistanceRequest.getSupplementMode())) {
            parameters.append("&supplement_mode=").append(getDistanceRequest.getSupplementMode());
        }
    }

    /**
     * 组装获取里程参数表
     *
     * @param getTrackRequest
     * @param parameters
     */
    public static void packTrack(GetTrackRequest getTrackRequest, StringBuilder parameters) {
        packDistance(getTrackRequest, parameters);
        if (StringUtils.isNotEmpty(getTrackRequest.getCoordTypeOutput())) {
            parameters.append("&coord_type_output=").append(getTrackRequest.getCoordTypeOutput());
        }
        if (StringUtils.isNotEmpty(getTrackRequest.getSortType())) {
            parameters.append("&sort_type=").append(getTrackRequest.getSortType());
        }
        if (getTrackRequest.getPageIndex() != 0) {
            parameters.append("&page_index=").append(getTrackRequest.getPageIndex());
        }
        if (getTrackRequest.getPageSize() != 0) {
            parameters.append("&page_size=").append(getTrackRequest.getPageSize());
        }
    }

    /**
     * 组装获取entity请求列表
     *
     * @param listEntityRequest
     * @param parameters
     */
    public static void packListEntity(ListEntityRequest listEntityRequest, StringBuilder parameters) {
        if (StringUtils.isNotEmpty(listEntityRequest.getFilter())) {
            parameters.append("&filter=").append(listEntityRequest.getFilter());
        }
        if (StringUtils.isNotEmpty(listEntityRequest.getCoordTypeOutput())) {
            parameters.append("&coord_type_output=").append(listEntityRequest.getCoordTypeOutput());
        }
        if (listEntityRequest.getPageSize() != 0) {
            parameters.append("&page_size=").append(listEntityRequest.getPageSize());
        }
        if (listEntityRequest.getPageIndex() != 0) {
            parameters.append("&page_index=").append(listEntityRequest.getPageIndex());
        }
    }

    /**
     * 组装自定义属性（单个轨迹点）
     *
     * @param columns
     * @param parameters
     */
    public static void packColumns(Map<String, String> columns, StringBuilder parameters) {
        for (Map.Entry<String, String> entry : columns.entrySet()) {
            parameters.append("&").append(entry.getKey()).append("=").append(HttpUtils.urlEncode(entry.getValue()));
        }
    }

    /**
     * 组装自定义属性（批量轨迹点）
     *
     * @param columns    自定义属性
     * @param jsonObject json对象
     * @return
     */
    private static void packColumns(Map<String, String> columns, ObjectNode jsonObject) {
        for (Map.Entry<String, String> column : columns.entrySet()) {
            if (StringUtils.isEmpty(column.getKey()) || StringUtils.isEmpty(column.getValue())) {
                continue;
            }
            try {
                jsonObject.put(column.getKey(), HttpUtils.urlEncode(column.getValue()));
            } catch (Exception ex) {
                ex.printStackTrace();
            }
        }
    }

}
